#ifndef VERTEXBUFFER_H
#define VERTEXBUFFER_H

#include "Log.h"
#include "Exception.h"
#include "MemUtils.h"
#include "ErrorHandlers.h"
#include "GpuBuffer.h"
#include "VertexFormat.h"

namespace Cvekas {

class GpuBufferManager;

/// Vertex buffer
class VertexBuffer : public GpuBuffer
{
public:
	/// Constructor. You shouldn't construct VertexBuffer yourself, GpuBufferManager does this.
	VertexBuffer(ResourceId id, D3DDevicePtr device, const std::string& name,
		VertexFormat format, uint vertex_count, bool is_dynamic);

	/// Destructor
	virtual ~VertexBuffer();

	/// Is vertex buffer locked?
	virtual bool isLocked() const;

	/// Locks vertex buffer. Throws Exception if buffer is already locked.
	/// \param read_only Pass true if no writing to locked buffer will be done, it improves performance.
	virtual LockedBuffer lock(bool read_only);
	/// Unlocks locked buffer. Throws Exception if buffer is not locked.
	virtual void unlock();

	/// Returns number of vertices in buffer.
	uint getVertexCount() const;
	/// Returns format of vertices.
	VertexFormat& getVertexFormat();

	/// Returns pointer to IDirect3DVertexBuffer9
	IDirect3DVertexBuffer9* getD3DVertexBuffer() const;

	/// You shouldn't call this
	virtual void onDeviceLost();
	/// You shouldn't call this
	virtual void onDeviceReset();

private:	
	void create();

	const uint vertex_count;
	VertexFormat format; // Don't change this with format.set*** methods
	bool is_locked;
	DWORD usage;
	IDirect3DVertexBuffer9* vertex_buffer;

};

typedef boost::shared_ptr<VertexBuffer> VertexBufferPtr;

} // namespace

#endif